/*! jQuery Array v1.3 ~ Sean Catchpole - Copyright 2010 MIT/GPL */
;(function($){ if(!$) return;
  $.fn.join = [].join;
  $.fn.reverse = function(){ return this.pushStack( [].reverse.apply( this, arguments ) ); };
  $.fn.limit = function(a,b){ return this.pushStack( [].slice.call( this, b&&a||0, b||a ) ); };
  $.fn.reduce = function(f,z) {
    var l=this.length||0;
    z=typeof z=="undefined"?(l?this[0]:0):z;
    while(l--){ z=f.call(this[l],z,l,this[l]); }
    return z;
  };
  var map = $.fn.map;
  $.fn.map = function(f){
    if(typeof f == "string"){ var p=f; f=function(){ return this[p]; }; }
    return map.call(this,f);
  };
  $.fn.sum = function(){ return this.reduce(function(z){ return z+this; },0); };
  $.fn.avg = function(){ return this.length&&this.sum()/this.length||0; };
  $.fn.min = function(){ return this.reduce(function(z){ return this<z?this:z; },Number.MAX_VALUE); };
  $.fn.max = function(){ return this.reduce(function(z){ return this>z?this:z; },Number.MIN_VALUE); };
  $.fn.diff = function(){ var self=this; return self.map(function(i){ return i&&self[i]-self[i-1]||null; }); };
  $.fn.sort = function(){
    var fast = function(p,f) {
      if(!this.length) return;
      var s = "toString"
        , op = Object.prototype, o = op[s]
        , ap = Array.prototype,  a = ap[s]
        , i = function(){ return this; }
        , k = function(){ return this[p]; };
      if(typeof p == "function"){
        if(!f){ f=p; p=null; }
        else{ i=p; }
      }else{ i=k; }
      var n = !f && typeof (p?i.call(this[this.length-1]):this[this.length-1]) == "number";
      if(n){ f = function(a,b){ return a-b; }; }
      if(p){ op[s] = i; ap[s] = i; }
      ( f ? [].sort.call(this,f) : [].sort.call(this) );
      if(p){ op[s] = o; ap[s] = a; }
      return this;
    };
    return this.pushStack( fast.apply( this , arguments ) );
  };
  $.fn.sortBy = function(list,p,f){
    if(!this.length || !list || !list.length) return this;
    var i, newList=[], sortList=[];
    for(i=0; i<this.length; i++){
      sortList.push( {key:i,value:list[i%list.length]} );
    }
    sortList = $(sortList).sort("value",p,f);
    for(i=0; i<sortList.length; i++){
      newList.push( this[ sortList[i].key ] );
    }
    return this.pushStack( newList );
  };
  

  var addType = function(i,m){
    if($.fn[m] && !$.fn[this+'s']){
      $.fn[this+'s']=function(){
        var args=arguments;
        return this.map(function(){ return $(this)[m].apply($(this),args); });
      };
    }
  };
  $.each("attr|offset|position|scrollTop|scrollLeft|innerWidth|innerHeight|outerWidth|outerHeight|width|height|html|text|val|data".split('|'),addType);
  addType.call("style",0,"css");

  // Load data attribute automatically (included in jQuery 1.4.3)
  $.fn.data = (function(undefined){
    var data = $.fn.data;
    return function(key,value){
      var res = data.call(this,key,value);
      if(res==undefined && key){
        res = this.attr('data-'+key);
        if(/\d/.test(res) && !isNaN(res)) res = parseFloat(res);
        if(res!=undefined){
          data.call(this,key,value==undefined?res:value);
        }
      }
      return res;
    };
  })();
  $.fn.dataSort = function(key){ return this.sort(function(){ return $(this).data(key); }); };

})(jQuery);
